//
//  DDroppingLayoutManager.swift
//  Drop
//
//  Created by hushaohua on 2017/12/21.
//  Copyright © 2017年 init. All rights reserved.
//

import UIKit

class DDroppingLayoutManager: NSObject,UIGestureRecognizerDelegate {
    
    lazy var tap:UITapGestureRecognizer = {
        var tap = UITapGestureRecognizer(target: self, action: #selector(tapWindow(_:)));
        tap.delegate = self;
        return tap;
    }();
    
    lazy var pan:UIPanGestureRecognizer = {
        var pan = UIPanGestureRecognizer(target: self, action: #selector(panWindow(_:)));
        pan.delegate = self;
        return pan;
    }();
    
    func swipeTo(_ direction:UISwipeGestureRecognizerDirection) -> UISwipeGestureRecognizer{
        let swipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeWindow(_:)));
        swipe.direction = direction;
        swipe.delegate = self;
        return swipe;
    }
    
    lazy var swipes:[UISwipeGestureRecognizer] = {
        var swipes = [UISwipeGestureRecognizer]();
        swipes.append(self.swipeTo(.left));
        swipes.append(self.swipeTo(.right));
        swipes.append(self.swipeTo(.up));
        swipes.append(self.swipeTo(.down));
        return swipes;
    }();
    
    func maximum(_ animated:Bool) -> Void {
        self.layoutWith(small: false, animated: animated);
    }
    func minimum(_ animated:Bool) -> Void {
        self.layoutWith(small: true, animated: animated);
    }

    var panBeginLocation:CGPoint = .zero;
    @objc func panWindow(_ sender:UISwipeGestureRecognizer) -> Void{
        switch sender.state {
        case .began:
            self.panBeginLocation = sender.location(in: self.window);
        case .changed:
            let keyLocation:CGPoint = sender.location(in: UIApplication.shared.keyWindow);
            self.smallWindowFrame.origin = CGPoint(x:keyLocation.x - self.panBeginLocation.x, y:keyLocation.y - self.panBeginLocation.y);
            self.window?.frame = self.smallWindowFrame;
        default:
            break;
        }
    }
    @objc func swipeWindow(_ sender:UISwipeGestureRecognizer) -> Void{
        self.resetSmallWindowFrame(sender.direction);
        self.layoutWith(small: !self.isSmall, animated: true);
    }
    @objc func tapWindow(_ sender:UITapGestureRecognizer) -> Void{
        if (self.view?.superview != nil){
            self.layoutWith(small: !self.isSmall, animated: true);
        }else{
            self.intoView?.textField.resignFirstResponder();
        }
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        
        if self.isSmall{
            if (self.tap == gestureRecognizer){
                return true;
            }else if (self.pan == gestureRecognizer){
                return true;
            }else{
                return false;
            }
        }else{
            if (self.tap == gestureRecognizer){
                let point = touch.location(in: self.view);
                return (self.view != nil) && !(self.view!.bounds.contains(point));
            }else{
                if (self.view?.superview != nil && gestureRecognizer is UISwipeGestureRecognizer){
                    let point = touch.location(in: self.view);
                    return (self.view != nil) && (self.view!.bounds.contains(point));
                }else{
                    return false;
                }
            }
        }
    }
    
    func layoutWith(small:Bool, animated:Bool) -> Void {
        if (animated){
            if (self.layoutWillChanged != nil){
                self.layoutWillChanged!();
            }
            UIView.animate(withDuration: 0.2, animations: {
                self.isSmall = small;
            }, completion: { (finished) in
                if (self.layoutDidChanged != nil){
                    self.layoutDidChanged!();
                }
            });
        }else{
            self.isSmall = small;
        }
    }
    
    var window:UIWindow?{
        didSet{
            if (window != nil){
                if (self.tap.view != window){
                    window!.addGestureRecognizer(self.tap);
                }
                if (self.pan.view != window){
                    window!.addGestureRecognizer(self.pan);
                }
                self.pan.require(toFail: self.tap);
                for swipe in self.swipes {
                    if (swipe.view != window){
                        window!.addGestureRecognizer(swipe);
                    }
                }
            }
            self.layoutWindow();
        }
    }
    var view:DDroppingView?{
        didSet{
            self.layoutView();
        }
    }
    var intoView:DDropIntoView?;
    
    func layoutWindow() -> Void {
        
        if !self.isSmall{
            self.window?.frame = self.largeWindowFrame;
        }else{
            self.window?.frame = self.smallWindowFrame;
        }
    }
    
    func layoutView() -> Void {
        
        if !self.isSmall{
            view?.dropSize = self.largeDropSize();
            view?.intervalSize = self.largeIntervalSize();
            view?.dropView.dripSize = self.largeDripSize;
            view?.frame = self.largeViewFrame();
        }else{
            view?.dropSize = self.smallDropSize;
            view?.intervalSize = self.smallIntervalSize;
            view?.dropView.dripSize = self.smallDripSize;
            view?.frame = self.smallViewFrame();
        }
    }
    
    var layoutWillChanged:(() -> Void)?;
    var layoutDidChanged:(() -> Void)?;
    var isSmall:Bool = false{
        didSet{
            if (oldValue != isSmall){
//                self.view?.intervalButton.isEnabled = !isSmall;
                self.layoutWindow();
                self.layoutView();
            }
        }
    }
    
    let hMarginOfLarge:CGFloat = 40;
    let topMarginOfLarge:CGFloat = 100;
    let bottomMarginOfLarge:CGFloat = 70;
    
    //MARK: - large
    var largeWindowFrame:CGRect = CGRect(origin:.zero, size:UIScreen.main.bounds.size);
    func largeViewFrame() -> CGRect { //droppingview
        let size:CGSize = UIScreen.main.bounds.size;
        return CGRect(x:hMarginOfLarge,y:topMarginOfLarge,width:size.width - 2  * hMarginOfLarge,height:size.height - topMarginOfLarge - bottomMarginOfLarge);
    }
    func largeDropSize() -> CGSize{ //drop down
        let viewSize:CGSize = self.largeViewFrame().size;
        return CGSize(width:80, height:viewSize.height - 25);
    }
    func largeIntervalSize() -> CGSize{
        let viewSize:CGSize = self.largeViewFrame().size;
        return CGSize(width:viewSize.width, height:50);
    }
    let largeDripSize:CGSize = CGSize(width:80,height:60);
    
    //MARK: - small
    var smallWindowFrame:CGRect = CGRect(x:10,y:UIScreen.main.bounds.size.height - 180,width:60,height:80);
    func smallViewFrame() -> CGRect {
        return CGRect(origin:.zero, size:self.smallWindowFrame.size);
    }
    let smallDropSize:CGSize = CGSize(width:60,height:70);
    let smallIntervalSize:CGSize = CGSize(width:60,height:20);
    let smallDripSize:CGSize = CGSize(width:40,height:30);
    
    func resetSmallWindowFrame(_ direction:UISwipeGestureRecognizerDirection) -> Void {
        let size:CGSize = UIScreen.main.bounds.size;
        switch direction {
        case .left:
            self.smallWindowFrame = CGRect(x:10,y:size.height - 180,width:60,height:80);
        case .right:
            self.smallWindowFrame = CGRect(x:size.width - 10 - 60,y:size.height - 180,width:60,height:80);
        case .up:
            self.smallWindowFrame = CGRect(x:10,y:80,width:60,height:80);
        case .down:
            self.smallWindowFrame = CGRect(x:size.width - 10 - 60,y:size.height - 180,width:60,height:80);
        default:
            break;
        }
    }
}
